package com.itzz.spring_zhoneHeng.config;

import com.itzz.spring_zhoneHeng.service.MyUserDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.Authentication;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.jws.Oneway;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;
import java.io.IOException;
import java.net.PasswordAuthentication;

@Configuration
//  此为创建类后 最开始的第二步 将密码加密放进容器里面
//  第三步继承WebSecurityConfigurerAdapter  重写configure的拦截方法
public class securityConfig extends WebSecurityConfigurerAdapter {

    //权限不足403
    @Autowired
    MyAccessDeniedHandler myAccessDeniedHandler;
    //登录拦截逻辑
    @Autowired
    MyUserDetailsService myUserDetailsService;
    //登录成功后创建token
    @Autowired
    MyAuthenticationSuccessHandler myAuthenticationSuccessHandler;
    //登录失败 402  (用户名或密码错误)
    @Autowired
    MyAuthenticationFailureHandler myAuthenticationFailureHandler;
    //401用户未登录
    @Autowired
    MyAuthenticationEntryPoint myAuthenticationEntryPoint;
    //拦截token
    @Autowired
    JwtFile jwtFile;


    @Override
    protected void configure(HttpSecurity http) throws Exception {
//        super.configure(http);
        //开启登录拦截                            拦截所有路径中第二个拦截的
        http.formLogin()
                .loginPage("/login.html")
   //登录访问的路径  登录逻辑入口        匹配form表单(vue前端)路径如果匹配成功 则进入自定义登录逻辑
                .loginProcessingUrl("/login")
   //登录成功本地访问页面(本地)  自定义登录成功处理器
//                .successForwardUrl("/index")//直接访问时不写Controller后台/index路径时  默认为get请求
   //登录失败本地访问页面(本地)  自定义登录失败处理器
//                .failureForwardUrl("/error1")
   //登录成功到别的地方访问页面   自定义登录成功处理器
                .successHandler(myAuthenticationSuccessHandler)
   //登录失败本地访问页面  自定义登录失败处理器
                .failureHandler(myAuthenticationFailureHandler);
        //开启权限认证拦截(这里是拦截所有的路径)          拦截所有路径中第一个拦截的
        http.authorizeRequests()
                //放行路径
                .antMatchers("/login.html").permitAll()
                .antMatchers("/login").permitAll()
                .antMatchers("/error.html").permitAll()
                .antMatchers("/img/**").permitAll()
                //只允许已认证的用户访问   /user/**  放行user路径下的所有请求
//                .antMatchers("/cart").hasAnyAuthority("user","admin")
//                .antMatchers("/cart").hasAnyRole("c")
//                .antMatchers("/cart").hasIpAddress("172.19.10.78") 需要将localhost改成你本机的ip地址才能访问
                .anyRequest().authenticated();
        //解析所有页面携带的token信息     //权限认证拦截之前(这里是拦截所有的路径)
        http.addFilterBefore(jwtFile, UsernamePasswordAuthenticationFilter.class);

        //自定义异常处理
        http.exceptionHandling()
                //403处理页面(无权限)
                .accessDeniedHandler(myAccessDeniedHandler)
                //401用户未登录
                .authenticationEntryPoint(myAuthenticationEntryPoint);
        //禁用session  禁用Session登录保持
        http.sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS);

        //允许跨站请求  关闭csrf防护   可以vue访问后台
        http.csrf().disable();

    }

    @Bean
    //将密码进行加密 放进容器中
    public PasswordEncoder pw(){
        return new BCryptPasswordEncoder();
    }
//    @Bean
//    DataSource dataSource;
}
